package cn.cxyxj;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * 年龄断言工厂，限制未成年人及老年人不能访问
 */
@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {

    public AgeRoutePredicateFactory() {
        super(AgeRoutePredicateFactory.Config.class);
    }

    /**
     * 从配置文件中获取参数值，赋值到配置类（Config）中的属性上
     *
     */
    public List<String> shortcutFieldOrder() {
        // 顺序要跟配置文件中的参数顺序一致
        return  Arrays.asList("minAge", "maxAge");
    }

    @Override
    public Predicate<ServerWebExchange> apply(AgeRoutePredicateFactory.Config config) {
        Assert.isTrue(config.getMinAge() < config.getMaxAge(),  "最小年龄值不能大于最大年龄值");
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange exchange) {
                //1、接收请求传入的age参数
                String ageStr = exchange.getRequest().getQueryParams().getFirst("age");
                //2、先判断是否为空
                if (Objects.nonNull(ageStr) && ageStr!="") {
                    //3、不为空,进行路由逻辑判断
                    int age = Integer.parseInt(ageStr);
                    if (age < config.getMaxAge() && age > config.getMinAge()) {
                        return true;
                    } else {
                        return false;
                    }
                }
                // 为空，返回 false
                return false;
            }

            public String toString() {
                return String.format("Age: %s - %s", config.getMinAge(),config.getMaxAge());
            }
        };
    }


    /**
     * 接收配置文件中的参数
     */
    public static class Config {
        private int minAge;
        private int maxAge;

        public Config() {
        }

        public int getMinAge() {
            return minAge;
        }

        public void setMinAge(int minAge) {
            this.minAge = minAge;
        }

        public int getMaxAge() {
            return maxAge;
        }

        public void setMaxAge(int maxAge) {
            this.maxAge = maxAge;
        }

    }
}
